<template>
    <div class="bi-calendar-box">
        <div class="calendar-header" >
            <div class="header-item">
                <div class="button" @click.stop="yearUp" >
                    <i class="fa fa-chevron-left"></i>
                </div>
                <div class="calendar-header-title">
                    <div v-dropdown  dropdown-center dropdown-body="year-body" class="title-pop">{{currentYear}}年</div>
                    <div ref="year-body" class="dropdown-menu">
                        <div class="bi-calendar-year-list-btn" @click.stop
="yearListUp">
                            <i class="fa fa-chevron-up"></i>
                        </div>
                        <div  class="bi-calendar-pop-box">
                            <div class="item" v-for="(item,index ) in yearList" :key="index" @click="changeYear(item)">
                                {{item}}年
                            </div>
                        </div>
                        <div class="bi-calendar-year-list-btn" @click.stop
="yearListDown">
                            <i class="fa fa-chevron-down"></i>
                        </div>
                    </div>    
                </div>
                <div class="button" @click.stop="yearDown">
                    <i class="fa fa-chevron-right"></i>
                </div>
                
            </div>
            <div class="header-item" v-if="title!='' && title!=undefined ">
                <div class="title">{{title}}</div>
            </div>
            <div class="header-item">
                
                <div class="button" @click.stop="monthUp">
                    <i class="fa fa-chevron-left"></i>
                </div>
                <div class="calendar-header-title">
                   <div v-dropdown dropdown-center dropdown-body="month-body" class="title-pop">{{currentMonth}}月</div>
                    <div ref="month-body" class="dropdown-menu ">   
                        <div class="bi-calendar-pop-box">
                            <div class="item" v-for="(item,index ) in monthList" :key="index" @click="changeMonth(item)">
                                {{item}}月
                            </div>
                        </div>
                    </div>
                </div>
                <div class="button" @click.stop="monthDown">
                    <i class="fa fa-chevron-right"></i>
                </div>
            </div>
        </div>
        <div class="week-header">
            <div class="week-item">一</div>
            <div class="week-item">二</div>
            <div class="week-item">三</div>
            <div class="week-item">四</div>
            <div class="week-item">五</div>
            <div class="week-item weekend">六</div>
            <div class="week-item weekend">日</div>
        </div>

        <div class="day-body">
            <div class="day-item"  v-for="(item,index) in daylist" :key="index" :class="[item.className,item.month]" @click="hanlderDayClick(item,index)" >
                <div class="day-item-wrapper">
                    <div class="day-number"><i class="dot"></i>{{item.day}}</div>
                    <slot></slot>
                </div>
            </div>
        </div>
        
    </div>
</template>


<script>
export default {
    data(){
        
        return {
            yearLab:0,
            yearList:[],
            monthList:[],
            daylist:[],
            currentYear: parseInt(this.year),
            currentMonth:parseInt(this.month),
        }

    },
    name:'bi-calender',
    props:{
        year:{
            type:Number,
            default:new Date().getFullYear()
        },
        month:{
            type:Number,
            default:new Date().getMonth() + 1
        },
        title:{
            type:String,
            default:''
        },
        select:{
            type:Boolean,
            default:false
        },
        range:{
            type:Boolean,
            default:false
        },
        cross:{
            type:Boolean,
            default:null
        },
        max:Date,
        min:Date,
        modelValue:{
            type:[Date,Array],
        },
    },
    computed:{
        value:{
            get(){
                if ( this.range &&  ! (this.modelValue  instanceof Array )){
                    return [];
                }

                return this.modelValue;
            },
            set(val){
                this.$emit('update:modelValue',val);
            }
        },
    },
    emits:['change','update:modelValue'],
    watch:{
        year(val){
            val  = parseInt(val);
            if (val!=this.currentYear){
                this.currentYear = val;
            }
        },
        month(val){
            val  = parseInt(val);
            if (val!=this.currentMonth){
                this.currentMonth = val;
            }
        },
        currentYear(val){
            this.updateDayBody();
            this.$emit('change',{year:val,month:this.currentMonth});
        },
        currentMonth(val){
            this.updateDayBody();
            this.$emit('change',{year:this.currentYear,month:val});
        },
    },
    methods:{
        hanlderDayClick(item,index){
            
            if (this.select){

                if (item.month != 'current') return;

                if (!this.range){
                    this.value = item.date;
                    this.updateDayClass(item.date);
                }else{

                    
                    //跨日历
                    let now = item.date;
                    let value = [];

                    switch(this.value.length){
                        case 0:
                            value = [item.date];
                        break;
                        case 1:

                            if (this.value[0] - item.date == 0) return;

                            if (now > this.value[0]){
                                value = [this.value[0], item.date];
                            }else{
                                value = [now, this.value[0]];
                            }
                        break;
                    }
                    
                    this.value = value;
                    this.updateDayClass(value);
                }
            }
        },
        //切换事件
        yearUp(){
            this.currentYear --;
        },
        yearDown(){
            this.currentYear ++;
        },
        changeYear(num){
            this.currentYear = parseInt(num);
        },
        updateYearList(yearLab){

            if (this.yearLab != yearLab){
                this.yearLab =  yearLab;
                let i ;
                let yearList = new Array();
                for(i=0;i<10;i++){
                    yearList[i] =  yearLab*10+i;
                }

                this.yearList = yearList;
            }

        },
        yearListUp(event){
           // console.log(event);
           event.stopPropagation();
           this.updateYearList(this.yearLab -1);
        },

        yearListDown(event){
           // console.log(event);
           event.stopPropagation();
           this.updateYearList(this.yearLab +1);
        },
        changeMonth(num){
            this.currentMonth = parseInt(num);
        },
        monthUp(){
            
            if (this.currentMonth==1){
                this.currentMonth = 12;
                this.currentYear --;
            }else{
                this.currentMonth --;
            }

        },
        monthDown(){
        
            if (this.currentMonth==12){
                this.currentMonth  =1;
                this.currentYear ++;
            }else{
                this.currentMonth ++;
            }

        },
        updateDayBody(){
            let  _year  = this.currentYear;
            let  _month = this.currentMonth;

            if (this.monthList.length==0){
                let i=1;
                for(i=1;i<=12;i++){
                    this.monthList.push(i);
                }
            }

            this.updateYearList(Math.floor(_year/10));

            let getCountDays =  function(year,month){
 
                var curDate = new Date(year,month,0);
                
                return curDate.getDate();

            }

            let  getUpMonthDays = function (year,month){
                if (month==1) {
                    year = year -1;
                    month = 12;
                }else{
                    month = month-1;
                }

                var curDate = new Date(year,month,0);
                
                return curDate.getDate();

            }

            let getWeek =  function(year,month,day){
                var curDate = new Date(year,month-1,day);
                return curDate.getDay();
            }


            let days  = getCountDays(_year,_month);
            let week  = getWeek(_year,_month,1);
            let up_days = getUpMonthDays(_year,_month);
        
            let daylist  = [];
            let i,index=0;

            for(i = up_days-week+2;i<=up_days;i++){
                daylist[index] = {
                    month:'up',
                    className:'',
                    day:i,
                    date:new Date(_year,_month-2,i)
                }

                index ++;
            }

            for(i=1;i<=days;i++){

                daylist[index] = {
                    month:'current',
                    className:'',
                    day:i,
                    date:new Date(_year,_month-1,i)
                }

                index ++;
            }


            let down_number = daylist.length%7;
            if (down_number!=0){
                let start=1;
                for(i=down_number;i<=6;i++){
                    daylist[index] = {
                        month:'down',
                        className:'',
                        day:start,
                        date:new Date(_year,_month,start)
                    }
                    start ++;
                    index ++;
                }
            }
            
            this.daylist = daylist;
            this.updateDayClass(this.value);
            this.$forceUpdate();
        },
        updateDayClass(value){
            
            this.daylist.forEach((item,index)=>{
                
                if (value == undefined || item.month !='current') {
                    item.className = '';
                    return;
                };


                
                if (this.range){
                    item.className = '';

                    //console.log(value[0],item.date,item.date - value[0]);
                    if (value[0] instanceof Date   && item.date - value[0] === 0){
                        item.className = 'select range-select';
                    }

                    if (value[1] instanceof Date   && item.date - value[1] === 0){
                        item.className = 'select range-select';
                    }

                    if (value.length === 2){
                        if (item.date - value[0] > 0 && item.date - value[1] < 0){
                            item.className = 'range-select';
                        }
                    }

                 
                    
                }else{     
                    value  = this.clearTime(value);            
                    if (item.date - value === 0){
                        item.className = 'select';
                    }else{
                        item.className = '';
                    }
                }
            });  
        },
        clearTime(date){
            return new Date(
                date.getFullYear(),
                date.getMonth(),
                date.getDate()
            )
        },
        clearSelect(){
            this.value = undefined;
            this.updateDayClass();
        }
    },
    
    mounted(){
        this.updateDayBody(true);
    },
    
    setup(props,{attrs}){
 
    }
}

//更新
</script>


<style>
    .bi-calendar-box{
        display: flex;
        flex-direction: column;
        background-color: #FFFFFF;
        justify-content: space-between;
        min-width: 200px;
    }
    .bi-calendar-box .calendar-header{
        background-color: rgba(0,0,0,.05);
        height: 40px;
        min-height: 40px;
        flex: 0;
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        -webkit-user-select: none; /* Safari */
        -ms-user-select: none; /* IE 10+ and Edge */
        user-select: none; /* Standard syntax */
    }

    .bi-calendar-box .calendar-header .header-item{ 
        display: flex;
        flex: 1;
        flex-direction: row;
        justify-content: space-between;
        align-items: center;
    }

    .bi-calendar-box .calendar-header .header-item .button{
        cursor: pointer;
        width: 20%;
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        height:100%;
    }
    .bi-calendar-box .calendar-header .header-item .calendar-header-title{
        flex:1;
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        
        
    }
    .bi-calendar-box .calendar-header .header-item .calendar-header-title .title-pop{
        position: relative;
        cursor: pointer;
        min-height:30px;
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
    }

    .bi-calendar-box .calendar-header .header-item .calendar-header-title .title-pop:before{
        content: '';
        position: absolute;
        width: 10px;
        height: 10px;
        right: -13px;
        top: 50%;
        margin-top: -2px;
        z-index: 1;
        transform:rotate(-180deg);
        border-left: 5px solid transparent;
        border-right: 5px solid transparent;
        border-bottom: 5px solid #AAAAAA;
    }

 

    .bi-calendar-box .week-header{
        display: grid;
        grid-template-columns: repeat(7, 1fr);
        width: 100%;
        justify-content: space-between;
        height: 30px;
        flex: 0;
        border-bottom: 1px solid rgba(0,0,0,.125);
    }

    .bi-calendar-box .week-header .week-item{
        text-align: center;
        flex: 1;
        line-height: 30px;
        -webkit-user-select: none; /* Safari */
        -ms-user-select: none; /* IE 10+ and Edge */
        user-select: none; /* Standard syntax */
    }

     .bi-calendar-box .week-header .week-item.weekend{
        color: red;
    }
 
     .bi-calendar-box .week-header .week-item:first-child{
          border-left:none;
     }

    .bi-calendar-box .day-body{
        flex: 1;
        display: grid;
        grid-template-columns: repeat(7, 1fr);
    }


    .bi-calendar-box  .day-item{
        text-align: center;
        flex: 1;
        
        line-height: 30px;
        -webkit-user-select: none; /* Safari */
        -ms-user-select: none; /* IE 10+ and Edge */
        user-select: none; /* Standard syntax */
        position: relative;
        display: flex;
        justify-content:center;
        align-items: center;
    }

    .bi-calendar-box  .day-item.up,
    .bi-calendar-box .day-item.down{
        color: #DDD;
    }

    .bi-calendar-box .day-item{
        cursor: pointer;
    }
    
    .bi-calendar-box  .day-item:hover{
        background-color: rgba(0,0,0,.025);
    }

    .bi-calendar-box .day-item.select{
        color: red;
        font-weight: bold;
    }

    .bi-calendar-box .day-item.range-select{
        background-color: rgba( var( --bs-primary-rgb ), 0.2);
    }

    .bi-calendar-pop-box{
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        padding: 10px 5px;
    }
    .bi-calendar-pop-box .item{
        width: 50%;
        line-height: 30px;
        text-align: center;
        display: block;
        cursor: pointer;
    }

    .bi-calendar-pop-box .item:hover{
        background-color: rgba(0,0,0,.025);
    }

    .bi-calendar-year-list-btn{
         display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        height: 30px;
        cursor: pointer;
    }

    .bi-calendar-year-list-btn:hover{
        background-color: rgba(0,0,0,.025);;
    }

    .calendar-header-title{
        position: relative;
    }

    .calendar-header-title .dropdown-menu{
        width: 160px;
        margin-left: -80px;
        left: 50%;
    }
</style>